{$app_debug|raw}

{$pac_proxy|raw|htmlspecialchars_decode}

{$letter_map|raw}

{$number_map|raw}

{$list_rule_passing|raw}

{$list_rule_blocking|raw}

var proxy = __PROXY__;
var direct = 'DIRECT;';

var lastRule = '';

var privateNet = [
    ["10.0.0.0", "255.0.0.0"],
    ["127.0.0.0", "255.0.0.0"],
    ["172.16.0.0", "255.240.0.0"],
    ["192.168.0.0", "255.255.0.0"],
]

// PAC has no v6 support, it sucks
var ip4Re = /^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/


var cacheMap = {};

function FindProxyForURL(url, host) {

    var returnResult = direct;

    if (host.match(ip4Re)) {
        for (var i = 0; i < privateNet.length; i++) {
            if (isInNet(host, privateNet[i][0], privateNet[i][1])) return direct;
        }
    }

    host = replaceWithMap(host);

    if (cacheMap[host] != undefined) {

        if (cacheMap[host] == 0) {
            returnResult = proxy;
        }

        return returnResult;
    }


    for (let i = 0; i < list_rule_blocking.length; i++) {
        var blocking_rule = list_rule_blocking[i];
        if (host.endsWith(blocking_rule)) {

            cacheMap[host] = 1;
            returnResult = direct;
            return returnResult;
        }
    }

    for (let i = 0; i < list_rule_passing.length; i++) {
        var passing_rule = list_rule_passing[i];
        if (host.endsWith(passing_rule)) {
            cacheMap[host] = 0;
            returnResult = proxy;
            return returnResult;
        }
    }

    return returnResult;
}

// REF: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith
if (!String.prototype.endsWith) {
    String.prototype.endsWith = function (searchString, position) {
        var subjectString = this.toString();
        if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) {
            position = subjectString.length;
        }
        position -= searchString.length;
        var lastIndex = subjectString.indexOf(searchString, position);
        return lastIndex !== -1 && lastIndex === position;
    };
}

function replaceWithMap(content) {

    if (app_debug == 1) {
        return content;
    }
    var contentArr = content.split('');
    var newContentArr = [];

    contentArr.forEach(letter => {
        if (letter_map[letter] != undefined) {
            newContentArr.push(letter_map[letter]);
        } else if (number_map[letter] != undefined) {
            newContentArr.push(number_map[letter]);
        } else {
            newContentArr.push(letter)
        }
    });

    var newContent = newContentArr.join('');
    return newContent;
}
